package cn.com.zero.common.auth.security.token;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;

import java.util.Collection;

/**
 * @author xiongxj
 * @version 1.0.0
 * @Description 手机验证码认证token，模仿 UsernamePasswordAuthenticationToken 进行实现
 * @createTime 2023/3/15 10:42
 */
public class MobileCodeAuthenticationToken extends AbstractAuthenticationToken {

    private final Object principal;

    private Object credentials;

    /**
     * 构造函数
     * 当进入 filter 后，创建了不同的 token 的构造函数
     *
     * @param principal   用户手机号，唯一确定用户身份的数据
     * @param credentials 用于资格验证的验证码
     */
    public MobileCodeAuthenticationToken(Object principal, Object credentials) {
        super(null);
        this.principal = principal;
        this.credentials = credentials;
        // 是否已经认证，false  , 在后续provider 中认证通过设置为 true
        this.setAuthenticated(false);
    }

    /**
     * 构造函数
     * 当 token 在 provider 中通过验证，调用该构造函数创建新的 token
     *
     * @param principal   用户信息
     * @param credentials 用于资格验证的验证码
     * @param authorities 用户的权限集合
     */
    public MobileCodeAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        this.credentials = credentials;
        super.setAuthenticated(true);
    }

    @Override
    public Object getCredentials() {
        return credentials;
    }

    @Override
    public Object getPrincipal() {
        return principal;
    }

    @Override
    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
        Assert.isTrue(!isAuthenticated,
                "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
        super.setAuthenticated(false);
    }

    @Override
    public void eraseCredentials() {
        super.eraseCredentials();
        this.credentials = null;
    }
}
